﻿

using HalconDotNet;
using System.Collections.ObjectModel;
using System;
using ViewROI;
using Prism.Events;
using COVID_19_LiquidFillUI.Common.Services;
using COVID_19_LiquidFillUI.Models;
using NLog;
using System.Threading;
using Newtonsoft.Json;
using System.Windows.Forms;
using System.IO;
using COVID_19_LiquidFillUI.Common.Extensions;
using System.Threading.Tasks;
using System.Linq;

namespace COVID_19_LiquidFillUI.ViewModels
{


    public class Station1ViewModel : BindableBase
    {
        #region 变量
        ICameraService cam0,cam1;
        IPLCModbusService plc;
        public readonly IEventAggregator aggregator;
        private static Logger logger = LogManager.GetCurrentClassLogger();
        CancellationTokenSource source;
        Param param;
        bool plcConnect = false;
        #endregion
        #region 属性绑定
        #region halcon
        #region 1#
        private HImage cameraIamge0;
        public HImage CameraIamge0
        {
            get { return cameraIamge0; }
            set { SetProperty(ref cameraIamge0, value); }
        }
        private bool cameraRepaint0;
        public bool CameraRepaint0
        {
            get { return cameraRepaint0; }
            set { SetProperty(ref cameraRepaint0, value); }
        }
        private ObservableCollection<ROI> cameraROIList0 = new ObservableCollection<ROI>();
        public ObservableCollection<ROI> CameraROIList0
        {
            get { return cameraROIList0; }
            set { SetProperty(ref cameraROIList0, value); }
        }
        private HObject cameraAppendHObject0;
        public HObject CameraAppendHObject0
        {
            get { return cameraAppendHObject0; }
            set { SetProperty(ref cameraAppendHObject0, value); }
        }
        private HMsgEntry cameraAppendHMessage0;
        public HMsgEntry CameraAppendHMessage0
        {
            get { return cameraAppendHMessage0; }
            set { SetProperty(ref cameraAppendHMessage0, value); }
        }
        private Tuple<string, object> cameraGCStyle0;
        public Tuple<string, object> CameraGCStyle0
        {
            get { return cameraGCStyle0; }
            set { SetProperty(ref cameraGCStyle0, value); }
        }
        #endregion
        #region 2#
        private HImage cameraIamge1;
        public HImage CameraIamge1
        {
            get { return cameraIamge1; }
            set { SetProperty(ref cameraIamge1, value); }
        }
        private bool cameraRepaint1;
        public bool CameraRepaint1
        {
            get { return cameraRepaint1; }
            set { SetProperty(ref cameraRepaint1, value); }
        }
        private ObservableCollection<ROI> cameraROIList1 = new ObservableCollection<ROI>();
        public ObservableCollection<ROI> CameraROIList1
        {
            get { return cameraROIList1; }
            set { SetProperty(ref cameraROIList1, value); }
        }
        private HObject cameraAppendHObject1;
        public HObject CameraAppendHObject1
        {
            get { return cameraAppendHObject1; }
            set { SetProperty(ref cameraAppendHObject1, value); }
        }
        private HMsgEntry cameraAppendHMessage1;
        public HMsgEntry CameraAppendHMessage1
        {
            get { return cameraAppendHMessage1; }
            set { SetProperty(ref cameraAppendHMessage1, value); }
        }
        private Tuple<string, object> cameraGCStyle1;
        public Tuple<string, object> CameraGCStyle1
        {
            get { return cameraGCStyle1; }
            set { SetProperty(ref cameraGCStyle1, value); }
        }
        #endregion
        #endregion
        #endregion
        #region 构造函数
        public Station1ViewModel(IContainerProvider containerProvider, IEventAggregator _aggregator)
        {
            aggregator = _aggregator;
            LoadParam();
            cam0 = containerProvider.Resolve<ICameraService>("Cam0");
            cam1 = containerProvider.Resolve<ICameraService>("Cam1");
            plc = containerProvider.Resolve<IPLCModbusService>("plc");
            var r1 = cam0.OpenCamera(param.Camera1Name);
            if (r1)
            {
                cam0.SetExposureTime(param.Camera1ExposureTime);
                aggregator.SendMessage("Camera0OpenOK", "Camera");
            }
            else
            {
                aggregator.SendMessage("Camera0OpenNG", "Camera");
            }
            var r2 = cam1.OpenCamera(param.Camera2Name);
            if (r2)
            {
                cam1.SetExposureTime(param.Camera2ExposureTime);
                aggregator.SendMessage("Camera1OpenOK", "Camera");
            }
            else
            {
                aggregator.SendMessage("Camera1OpenNG", "Camera");
            }
            if (r1 && r2)
            {
                source = new CancellationTokenSource();
                CancellationToken token1 = source.Token;
                Task.Run(() => Run(token1), token1);
            }
            aggregator.ResgiterMessage(arg => {
                switch (arg.Message)
                {
                    case "Closed":
                        if (source != null)
                        {
                            source.Cancel();
                        }
                        break;
                    case "PLCConnect":
                        plcConnect = true;
                        break;
                    default:
                        break;
                }
            }, "App");
        }
        #endregion
        #region 功能函数
        private void Run(CancellationToken token)
        {
            while (true)
            {
                if (token.IsCancellationRequested)
                {
                    return;
                }
                try
                {
                    if (plcConnect)
                    {
                        var m700 = plc.ReadMCoils(700 , 1);
                        if (m700 != null)
                        {
                            if (m700[0])
                            {
                                aggregator.SendMessage("工位1触发拍照。", "Message");
                                plc.WriteMCoil(700, false);
                                
                                var img0 = cam0.GrabImage();
                                CameraIamge0 = img0;
                                var img1 = cam1.GrabImage();
                                CameraIamge1 = img1;
                                if (param.IsSaveImage)
                                {
                                    try
                                    {
                                        string filepath = $"SaveImage\\0\\{DateTime.Now:yyyyMMdd}";
                                        DirectoryInfo dir = new DirectoryInfo(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, filepath));
                                        if (!dir.Exists)
                                        {
                                            Directory.CreateDirectory(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, filepath));
                                        }
                                        HOperatorSet.WriteImage(img0, "jpeg", 0, System.IO.Path.Combine(System.Environment.CurrentDirectory, filepath, $"{DateTime.Now:yyyyMMddHHmmss}.jpg"));
                                        filepath = $"SaveImage\\1\\{DateTime.Now:yyyyMMdd}";
                                        dir = new DirectoryInfo(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, filepath));
                                        if (!dir.Exists)
                                        {
                                            Directory.CreateDirectory(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, filepath));
                                        }
                                        HOperatorSet.WriteImage(img1, "jpeg", 0, System.IO.Path.Combine(System.Environment.CurrentDirectory, filepath, $"{DateTime.Now:yyyyMMddHHmmss}.jpg"));
                                    }
                                    catch (Exception ex)
                                    {
                                        aggregator.SendMessage(ex.Message,"Message");
                                    }                  
                                }
                                #region 计算图像1
                                bool totalResult1 = true;
                                var mdb = new MDbContext();
                                if (img0 != null)
                                {
                                    var points0 = mdb.MVisionPoint1s.Where(p => p.Kind == 0);
                                    if (points0.Any())
                                    {
                                        string filepath = $"Camera\\0";
                                        var points1 = points0.OrderBy(p => p.PcsOrder).ToList();
                                        foreach (var item in points1)
                                        {
                                            try
                                            {
                                                HObject rec1;
                                                HOperatorSet.ReadRegion(out rec1, System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, filepath, $"rec1_{item.PcsOrder}.hobj"));


                                                HObject ho_resultRegion; HTuple hv_result, mArea;
                                                ImageCalc.AreaCalc(img0, rec1, item.ThresholdMin, item.ThresholdMax, item.JudgeArea, out ho_resultRegion, out hv_result, out mArea);

                                                HTuple msgRow, mesColumn;
                                                HOperatorSet.RegionFeatures(rec1, "row", out msgRow);
                                                HOperatorSet.RegionFeatures(rec1, "column", out mesColumn);
                                                if (hv_result != 1)
                                                {
                                                    totalResult1 = false;
                                                    aggregator.SendMessage($"工位1相机1:[{item.PcsOrder}]判断有无:{mArea.D:f1}<{item.JudgeArea},失败", "Message");
                                                }
                                                System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                                                {
                                                    
                                                    //CameraAppendHMessage0 = new HMsgEntry($"{item.PcsOrder}", (int)msgRow.D, (int)mesColumn.D, "black", "image", "box", "true", 12, "mono", "true", "false");                                                
                                                    
                                                    if (hv_result == 1)
                                                    {
                                                        CameraGCStyle0 = new Tuple<string, object>("DrawMode", "fill");
                                                        CameraGCStyle0 = new Tuple<string, object>("Color", "green");
                                                        CameraAppendHObject0 = ho_resultRegion;
                                                    }
                                                    else
                                                    {
                                                        CameraGCStyle0 = new Tuple<string, object>("Color", "red");
                                                        CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                                                        CameraAppendHObject0 = rec1;
                                                    }
                                                }));
                                            }
                                            catch (Exception ex)
                                            {
                                                logger.Error(ex);
                                                totalResult1 = false;
                                                aggregator.SendMessage($"工位1相机1:[{item.PcsOrder}]判断有无:{ex.Message},失败", "Message");
                                            }
                                           
                                        }
                                    }
                                }
                                else
                                {
                                    totalResult1 = false;
                                }
                                #endregion
                                #region 计算图像2
                                bool totalResult2 = true;
                                if (img1 != null)
                                {
                                    var points0 = mdb.MVisionPoint1s.Where(p => p.Kind == 1);
                                    if (points0.Any())
                                    {
                                        string filepath = $"Camera\\1";
                                        var points1 = points0.OrderBy(p => p.PcsOrder).ToList();
                                        foreach (var item in points1)
                                        {
                                            try
                                            {
                                                HObject rec1;
                                                HOperatorSet.ReadRegion(out rec1, System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, filepath, $"rec1_{item.PcsOrder}.hobj"));


                                                HObject ho_resultRegion; HTuple hv_result, mArea;
                                                ImageCalc.AreaCalc(img1, rec1, item.ThresholdMin, item.ThresholdMax, item.JudgeArea, out ho_resultRegion, out hv_result, out mArea);

                                                HTuple msgRow, mesColumn;
                                                HOperatorSet.RegionFeatures(rec1, "row", out msgRow);
                                                HOperatorSet.RegionFeatures(rec1, "column", out mesColumn);
                                                if (hv_result != 1)
                                                {
                                                    totalResult2 = false;
                                                    aggregator.SendMessage($"工位1相机2:[{item.PcsOrder}]判断有无:{mArea.D:f1}<{item.JudgeArea},失败", "Message");
                                                }
                                                System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                                                {
                                                    
                                                    //CameraAppendHMessage1 = new HMsgEntry($"{item.PcsOrder}", (int)msgRow.D, (int)mesColumn.D, "black", "image", "box", "true", 12, "mono", "true", "false");
                                                                                                
                                                    if (hv_result == 1)
                                                    {
                                                        CameraGCStyle1 = new Tuple<string, object>("DrawMode", "fill");
                                                        CameraGCStyle1 = new Tuple<string, object>("Color", "green");
                                                        CameraAppendHObject1 = ho_resultRegion;
                                                    }
                                                    else
                                                    {
                                                        CameraGCStyle1 = new Tuple<string, object>("Color", "red");
                                                        CameraGCStyle1 = new Tuple<string, object>("DrawMode", "margin");
                                                        CameraAppendHObject1 = rec1;
                                                    }
                                                    
                                                }));
                                            }
                                            catch (Exception ex)
                                            {
                                                logger.Error(ex);
                                                totalResult2 = false;
                                                aggregator.SendMessage($"工位1相机2:[{item.PcsOrder}]判断有无:{ex.Message},失败", "Message");
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    totalResult2 = false;
                                }
                                #endregion

                                if (totalResult1 && totalResult2)
                                {                                    
                                    plc.WriteMCoil(702, true);
                                }
                                else
                                {                                    
                                    plc.WriteMCoil(703, true);
                                }

                                plc.WriteMCoil(701, true);
                                System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                                {
                                    if (totalResult1)
                                    {
                                        CameraAppendHMessage0 = new HMsgEntry("OK", 10, 10, "green", "window", "box", "false", 32, "mono", "true", "false");
                                    }
                                    else
                                    {
                                        CameraAppendHMessage0 = new HMsgEntry("NG", 10, 10, "red", "window", "box", "false", 32, "mono", "true", "false");
                                    }
                                    if (totalResult2)
                                    {
                                        CameraAppendHMessage1 = new HMsgEntry("OK", 10, 10, "green", "window", "box", "false", 32, "mono", "true", "false");
                                    }
                                    else
                                    {
                                        CameraAppendHMessage1 = new HMsgEntry("NG", 10, 10, "red", "window", "box", "false", 32, "mono", "true", "false");
                                    }
                                }));
                            }
                        }
                    }
                }
                catch { }
                Thread.Sleep(100);
            }
        }
        private void LoadParam()
        {
            try
            {
                //Json序列化，从文件读取
                string jsonString = File.ReadAllText(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Param.json"));
                param = JsonConvert.DeserializeObject<Param>(jsonString);
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }

        }
        #endregion
    }

}
